﻿using BCCommon;
using BCCommon.Enums;
using BCData.Trading.Purchase.GoodsPurchaseChecklist;
using BCDto.Trading.Purchase.GoodsPurchaseChecklist;
using BCEntity.Trading.Purchase.GoodsPurchaseChecklist;
using BCEntity.Common.EntityNameConst;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BCData.Trading.Purchase.GoodsPurchaseItem;
using BCData.Trading.Purchase.GoodsPurchase;
using BCDto.Sim.Admin.Admin;

namespace BCService.Trading.Purchase.GoodsPurchaseChecklist
{
    public class GoodsPurchaseChecklistService : IGoodsPurchaseChecklistService
    {
        private readonly IDatabaseContext databaseContext;
        private readonly IRedisService redisService;
        private readonly IGoodsPurchaseData goodsPurchaseData;
        private readonly IGoodsPurchaseChecklistData goodsPurchaseChecklistData;
        private readonly IGoodsPurchaseItemData goodsPurchaseItemData;
        private readonly string key = string.Format("{0}", EntityNameConst.GoodsPurchaseChecklistEntity);

        public GoodsPurchaseChecklistService(IDatabaseContext databaseContext,
            IRedisService redisService,
            IGoodsPurchaseData goodsPurchaseData,
            IGoodsPurchaseChecklistData goodsPurchaseChecklistData,
            IGoodsPurchaseItemData goodsPurchaseItemData)
        {
            this.databaseContext = databaseContext;
            this.redisService = redisService;
            this.goodsPurchaseData = goodsPurchaseData;
            this.goodsPurchaseChecklistData = goodsPurchaseChecklistData;
            this.goodsPurchaseItemData = goodsPurchaseItemData;
        }

        #region 检查商品采购清单是否存在
        public bool Exists(long goodsPurchaseChecklistId)
        {
            return this.goodsPurchaseChecklistData.Exists(goodsPurchaseChecklistId).GetAwaiter().GetResult();
        }
        #endregion

        #region 添加商品采购清单
        public GoodsPurchaseChecklistDto Add(GoodsPurchaseChecklistAppendDto requestDto,AdminDto adminDto)
        {
            if (!this.goodsPurchaseData.Exists(requestDto.GoodsPurchaseId).Result)
            {
                throw new ArgumentException("此采购单不存在!");
            }
            var oldPurchaseEntity = this.goodsPurchaseData.GetEntity(requestDto.GoodsPurchaseId).Result;
            if (oldPurchaseEntity.HandleTime.HasValue && oldPurchaseEntity.PaidDepositeAmount.HasValue && oldPurchaseEntity.PaidDepositeAmount.Value > 0)
            {
                throw new ArgumentException("此采购单已完成定金支付，无法再进行修改!");
            }

            var entity = requestDto.As<GoodsPurchaseChecklistEntity>();
            if (!this.goodsPurchaseItemData.Exists(entity.GoodsPurchaseItemId).Result)
            {
                throw new ArgumentException(string.Format("采购项Id：{0} 不存在!", entity.GoodsPurchaseItemId));
            }
            if (entity.PurchasePrice < 0)
            {
                throw new ArgumentException(string.Format("采购项Id：{0} 采购单价不应为负数金额!", entity.GoodsPurchaseItemId));
            }
            if (entity.PurchaseAmount < 0)
            {
                throw new ArgumentException(string.Format("采购项Id：{0} 采购总价不应为负数金额!", entity.GoodsPurchaseItemId));
            }

            var purchaseItemEntity = this.goodsPurchaseItemData.GetEntity(entity.GoodsPurchaseItemId).Result;
            entity.SaleGoodsCategoryId = purchaseItemEntity.SaleGoodsCategoryId;
            entity.GoodsPurchaseNo = oldPurchaseEntity.GoodsPurchaseNo;
            entity.CategoryName = purchaseItemEntity.CategoryName;
            entity.SaleGoodsId = purchaseItemEntity.SaleGoodsId;
            entity.GoodsName = purchaseItemEntity.GoodsName;
            entity.Sku = purchaseItemEntity.Sku;
            entity.SaleGoodsNormId = purchaseItemEntity.SaleGoodsNormId;
            entity.NormName = purchaseItemEntity.NormName;
            entity.NormNo = purchaseItemEntity.NormNo;
            entity.VendorCategoryId = purchaseItemEntity.VendorCategoryId;
            entity.VendorCategoryName = purchaseItemEntity.VendorCategoryName;
            entity.VendorId = purchaseItemEntity.VendorId;
            entity.VendorName = purchaseItemEntity.VendorName;
            entity.PurchaseUnit = purchaseItemEntity.PurchaseUnit;
            entity.PurchaseCount = purchaseItemEntity.PurchaseCount;
            entity.CreateAdminName = adminDto.FullName;
            entity.CreateAdminId = adminDto.AdminId;
            databaseContext.BeginTransaction();
            var result = this.goodsPurchaseChecklistData.Add(entity).GetAwaiter().GetResult();
            this.goodsPurchaseItemData.UpdateCreatedTask(result.GoodsPurchaseItemId).GetAwaiter().GetResult();
            databaseContext.Commit();
            return result.As<GoodsPurchaseChecklistDto>();
        }
        #endregion

        #region 修改商品采购清单
        public GoodsPurchaseChecklistDto Update(GoodsPurchaseChecklistPutDto putDto,AdminDto adminDto)
        {
            if (!this.Exists(putDto.GoodsPurchaseChecklistId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var oldChecklistDto = this.Get(putDto.GoodsPurchaseChecklistId);
            if (!this.goodsPurchaseData.Exists(oldChecklistDto.GoodsPurchaseId).Result)
            {
                throw new ArgumentException("此采购单不存在!");
            }
            var oldPurchaseEntity = this.goodsPurchaseData.GetEntity(oldChecklistDto.GoodsPurchaseId).Result;
            if (oldPurchaseEntity.HandleTime.HasValue && oldPurchaseEntity.PaidDepositeAmount.HasValue && oldPurchaseEntity.PaidDepositeAmount.Value > 0)
            {
                throw new ArgumentException("此采购单已完成定金支付，无法再进行修改!");
            }

            var entity = putDto.As<GoodsPurchaseChecklistEntity>();
            if (!this.goodsPurchaseItemData.Exists(entity.GoodsPurchaseItemId).Result)
            {
                throw new ArgumentException(string.Format("采购项Id：{0} 不存在!", entity.GoodsPurchaseItemId));
            }
            if (entity.PurchasePrice < 0)
            {
                throw new ArgumentException(string.Format("采购项Id：{0} 采购单价不应为负数金额!", entity.GoodsPurchaseItemId));
            }
            if (entity.PurchaseAmount < 0)
            {
                throw new ArgumentException(string.Format("采购项Id：{0} 采购总价不应为负数金额!", entity.GoodsPurchaseItemId));
            }

            var purchaseItemEntity = this.goodsPurchaseItemData.GetEntity(entity.GoodsPurchaseItemId).Result;
            entity.SaleGoodsCategoryId = purchaseItemEntity.SaleGoodsCategoryId;
            entity.GoodsPurchaseNo = oldPurchaseEntity.GoodsPurchaseNo;
            entity.CategoryName = purchaseItemEntity.CategoryName;
            entity.SaleGoodsId = purchaseItemEntity.SaleGoodsId;
            entity.GoodsName = purchaseItemEntity.GoodsName;
            entity.Sku = purchaseItemEntity.Sku;
            entity.SaleGoodsNormId = purchaseItemEntity.SaleGoodsNormId;
            entity.NormName = purchaseItemEntity.NormName;
            entity.NormNo = purchaseItemEntity.NormNo;
            entity.VendorCategoryId = purchaseItemEntity.VendorCategoryId;
            entity.VendorCategoryName = purchaseItemEntity.VendorCategoryName;
            entity.VendorId = purchaseItemEntity.VendorId;
            entity.VendorName = purchaseItemEntity.VendorName;
            entity.PurchaseUnit = purchaseItemEntity.PurchaseUnit;
            entity.PurchaseCount = purchaseItemEntity.PurchaseCount;
            entity.EditAdminName = adminDto.FullName;
            entity.EditAdminId = adminDto.AdminId;
            databaseContext.BeginTransaction();
            var result = this.goodsPurchaseChecklistData.Update(entity).GetAwaiter().GetResult();
            this.goodsPurchaseItemData.UpdateCreatedTask(result.GoodsPurchaseItemId).GetAwaiter().GetResult();
            databaseContext.Commit();
            string cacheKey = this.redisService.GetKey(key, entity.GoodsPurchaseChecklistId);
            this.redisService.DeleteAsync(cacheKey);
            return result.As<GoodsPurchaseChecklistDto>();
        }
        #endregion

        #region 删除商品采购清单
        public bool Delete(long goodsPurchaseChecklistId)
        {
            if (!this.Exists(goodsPurchaseChecklistId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var oldChecklistDto = this.Get(goodsPurchaseChecklistId);
            var oldPurchaseEntity = this.goodsPurchaseData.GetEntity(oldChecklistDto.GoodsPurchaseId).Result;
            if (oldPurchaseEntity.HandleTime.HasValue && oldPurchaseEntity.PaidDepositeAmount.HasValue && oldPurchaseEntity.PaidDepositeAmount.Value > 0)
            {
                throw new ArgumentException("此采购单已完成定金支付，无法再进行修改!");
            }
            
            var result = this.goodsPurchaseChecklistData.Delete(goodsPurchaseChecklistId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, goodsPurchaseChecklistId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 获取商品采购清单
        public GoodsPurchaseChecklistDto Get(long goodsPurchaseChecklistId)
        {
            string cacheKey = this.redisService.GetKey(key, goodsPurchaseChecklistId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.goodsPurchaseChecklistData.GetEntity(goodsPurchaseChecklistId).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromMinutes(30));
            return result.As<GoodsPurchaseChecklistDto>();
        }
        #endregion

        #region 获取商品采购清单列表
        public IEnumerable<GoodsPurchaseChecklistDto> GetList(long goodsPurchaseId)
        {
            string cacheKey = this.redisService.GetKey(key, goodsPurchaseId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                return this.goodsPurchaseChecklistData.GetList(goodsPurchaseId).GetAwaiter().GetResult();
            }, TimeSpan.FromMinutes(30));
            return result.As<IEnumerable<GoodsPurchaseChecklistDto>>();
        }
        #endregion

        #region 获取商品采购清单分页
        public PageableList<GoodsPurchaseChecklistDto> Query(long? goodsPurchaseId, string categoryName, string goodsName, string sku, string vendorName, string adminName, long? adminId, 
            DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
        {
            string cacheKey = this.redisService.GetKey(key, goodsPurchaseId, categoryName, goodsName, sku, vendorName, adminName, adminId, start, end, sortName, ascending, pageIndex, pageSize);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.goodsPurchaseChecklistData.Query(goodsPurchaseId, categoryName, goodsName, sku, vendorName, adminName, adminId,start, end, sortName, ascending, pageIndex, pageSize).GetAwaiter().GetResult();
                return new PageableList<GoodsPurchaseChecklistDto>
                {
                    Count = data.Item2,
                    Items = data.Item1.As<IEnumerable<GoodsPurchaseChecklistDto>>(),
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    ServerTime = DateTime.Now
                };
            }, TimeSpan.FromMinutes(30));

            return result;
        }
        #endregion
    }
}